package main

func main() {
	/*
		1.短变量的声明和赋值的语法要约：
		（1）使用“:=”操作符，变量的定义和初始化要同时完成
		（2）变量名后不要跟任何类型名，Go编译器完全靠右边的值进行推导
		（3）支持多值短变量声明赋值
		（4）只能用在函数和类型方法的内部

		2.“a, b := va, vb” 什么时候定义新变量，什么时候复用已存在变量有如下规则：
		（1）如果想编译通过，则 a 和 b 中至少有一个是新定义的局部变量
		（2）若已经存在了一个局部变量 a，则“a, b := va, vb”不会创建新变量 a，而是直接使用 va 赋值给 a，但是会创建新变量 b，并将 vb 赋值给 b
		（3）若所在的代码块中没有局部变量 a 和 b，但是全局命名空间有变量 a 和 b，则该语句会创建新的局部变量 a 和 b 并使用 va、vb初始化它们
			此时，所在的局部作用域类内，全局的 a 和 b 被屏蔽

		3.“=”和“:=”的区别：
		（1）“=”不会创建新变量，而是在当前赋值语句所在作用域由内向外逐层去搜寻变量，如果没有搜寻到相同变量名，则报编译错误
		（2）“:=”必须出现在函数或类型方法内部
		（3）“:=”至少要创建一个局部变量并初始化

        4.标识符的重声明：
            对同一个标识符的两次声明各自所在的代码块之间存在包含的关系，就会形成标识符的重声明
          标识符的遮蔽：
            对被包含在内部的代码块中的标识符进行操作时，只会涉及内部的这个标识符，而不会涉及外部代码块的那个同名标识符的现象。
	*/
	//此时main函数作用域里面没有n
	//所以创建新的局部变量n
	n, _ := foo()

	//访问的是全局变量n
	g() //0

	//访问的是main函数作用域下的n
	println(n) //1
}

var n int

func foo() (int, error) {
	return 1, nil
}

// 访问全局变量
func g() {
	println(n)
}
